package JChamp;

import java.io.Console;
import java.util.Calendar;
import java.util.Random;
import java.util.TimeZone;

import com.dukascopy.api.Configurable;
import com.dukascopy.api.IAccount;
import com.dukascopy.api.IBar;
import com.dukascopy.api.IChart.Type;
import com.dukascopy.api.IConsole;
import com.dukascopy.api.IContext;
import com.dukascopy.api.IEngine;
import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.IIndicators;
import com.dukascopy.api.IMessage;
import com.dukascopy.api.INewsFilter.IndexRegion;
import com.dukascopy.api.IHistory;
import com.dukascopy.api.IOrder;
import com.dukascopy.api.IStrategy;
import com.dukascopy.api.ITick;
import com.dukascopy.api.Instrument;
import com.dukascopy.api.JFException;
import com.dukascopy.api.OfferSide;
import com.dukascopy.api.Period;
import com.dukascopy.api.IIndicators.AppliedPrice;


public class Bobsley_v01_test implements IStrategy{
    
    private int _SL = 35;
    private int _TP = 70;
    private int _MAPeriod = 15;
    private int _SellStochKoef = 80;
    private int _BuyStochKoef = 20;
    private Instrument _GlobalInstrument = Instrument.EURUSD;
    
    private Period _GlobalPeriod = Period.ONE_HOUR;
    
    //��������� ����������
    private IIndicators indicators = null;
    private IConsole console;
    private IEngine engine = null;
    private IOrder order = null;
    private IHistory history;
    private IAccount account = null;
    
    private double _MA0 = 0;
    private double _MA1 = 0;
    private double _MA2 = 0;
    private double[] _Stoch = null;
    
    double lastAskTick = 0;
    double lastBidTick = 0;
    
    @Override
    public void onStart(IContext context) throws JFException {
        // TODO Auto-generated method stub
        engine = context.getEngine();
        indicators = context.getIndicators();
        this.console = context.getConsole();
        this.history = context.getHistory();
        this.account = context.getAccount();
    }

    @Override
    public void onTick(Instrument instrument, ITick tick) throws JFException {
        // TODO Auto-generated method stub
        if(!instrument.equals(_GlobalInstrument)){
            return;    
        }
        
        if(CheckDate(tick.getTime())){
            return;
        }
        
         lastAskTick = tick.getAsk();
         lastBidTick = tick.getBid();
    }

    @Override
    public void onBar(Instrument instrument, Period period, IBar askBar,
            IBar bidBar) throws JFException {
        // TODO Auto-generated method stub
        
        if(!period.equals(_GlobalPeriod))
            return;
        
        if(!instrument.equals(_GlobalInstrument)){
            return;    
        }
        
        if(CheckDate(bidBar.getTime())){
            return;
        }
        
        _MA0 = indicators.ema(instrument, period, OfferSide.BID, AppliedPrice.CLOSE, _MAPeriod, 0);
        _MA1 = indicators.ema(instrument, period, OfferSide.BID, AppliedPrice.CLOSE, _MAPeriod, 1);
        _MA2 = indicators.ema(instrument, period, OfferSide.BID, AppliedPrice.CLOSE, _MAPeriod, 2);
        _Stoch = indicators.stoch(instrument, period, OfferSide.BID, 5, 3, IIndicators.MaType.SMA, 3, IIndicators.MaType.SMA, 1);
        
        IBar bid1 = history.getBar(instrument, period, OfferSide.BID, 1);
        IBar ask1 = history.getBar(instrument, period, OfferSide.ASK, 1);
        
        console.getOut().println("_MA0 = " + _MA0);
        console.getOut().println("_MA1 = " + _MA1);
        console.getOut().println("_MA2 = " + _MA2);
        console.getOut().println("_Stoch = " + _Stoch[0]);
        boolean buyFlag = false;
        boolean sellFlag = false;
        
        if(engine.getOrders().size() == 0){
            
            double lot = 5;
            
            console.getOut().println("Equity = " + account.getEquity());
            console.getOut().println("Lot = " + lot);
            
            buyFlag = CheckBuyConditions(instrument,period);
            sellFlag = CheckSellConditions(instrument,period);
            
            if((_MA1 < _MA2) && (_MA0 < _MA1) && (bid1.getClose() < _MA0)  && (_Stoch[0] > _SellStochKoef)){
                order = engine.submitOrder(getLabel(instrument,"Main"), instrument, OrderCommand.SELL, lot, lastBidTick, 10,
                        lastBidTick + _SL*instrument.getPipValue(), lastBidTick - _TP*instrument.getPipValue());
            }
            if((_MA1 > _MA2) && (_MA0 > _MA1) && (ask1.getClose() > _MA0)  && (_Stoch[0] < _BuyStochKoef)){
                order = engine.submitOrder(getLabel(instrument,"Main"), instrument, OrderCommand.BUY, lot, lastAskTick, 10,
                        lastAskTick - _SL*instrument.getPipValue(), lastAskTick + _TP*instrument.getPipValue());
            }
        }
    }
    
    @Override
    public void onMessage(IMessage message) throws JFException {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void onAccount(IAccount account) throws JFException {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void onStop() throws JFException {
        // TODO Auto-generated method stub
        
    }
    
    protected boolean CheckBuyConditions (Instrument instrument, Period period) throws JFException{
        if(((history.getBar(instrument, period, OfferSide.BID, 1).getClose() - history.getBar(instrument, period, OfferSide.BID, 1).getOpen()) > 0) &&
        ((history.getBar(instrument, period, OfferSide.BID, 2).getClose() - history.getBar(instrument, period, OfferSide.BID, 2).getOpen()) > 0) &&
        ((history.getBar(instrument, period, OfferSide.BID, 3).getClose() - history.getBar(instrument, period, OfferSide.BID, 3).getOpen()) > 0)){
            return true;
        }
        return false;
    }
    
    protected boolean CheckSellConditions (Instrument instrument, Period period) throws JFException{
        if(((history.getBar(instrument, period, OfferSide.BID, 1).getClose() - history.getBar(instrument, period, OfferSide.BID, 1).getOpen()) < 0) &&
        ((history.getBar(instrument, period, OfferSide.BID, 2).getClose() - history.getBar(instrument, period, OfferSide.BID, 2).getOpen()) < 0) &&
        ((history.getBar(instrument, period, OfferSide.BID, 3).getClose() - history.getBar(instrument, period, OfferSide.BID, 3).getOpen()) < 0)){
            return true;
        }
        return false;
    }
    
    protected String getLabel(Instrument instrument, String com) {
        
        String label = instrument.name();
       
        Random generator = new Random();
        int r = generator.nextInt(99999);

        label = label.substring(0, 2) + label.substring(3, 5);
        
        label = label + r + com;
        label = label.toLowerCase();
        return label;
    }
    
    protected Boolean CheckDate(long time){
        
        Calendar calendar = Calendar.getInstance();
        calendar .setTimeZone(TimeZone.getTimeZone("GMT"));
        calendar .setTimeInMillis(time);
        
        int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
        int currentDay = calendar.get(Calendar.DAY_OF_WEEK);
        
        if(((currentDay == Calendar.FRIDAY) && (currentHour > 21)) || (currentDay == Calendar.SATURDAY) 
                || ((currentDay == Calendar.SUNDAY) && (currentHour < 22))){
            return true;
        }
        return false;
    }

}
